package com.zmh.service.httpclient;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zmh.dao.BookDao;
import com.zmh.dao.BookFavDao;
import com.zmh.dao.BookLinkDao;
import com.zmh.model.book.BookFav;
import com.zmh.model.book.BookInfo;
import com.zmh.model.httpclient.HttpHeader;

/**
 * 短网址服务
 * @author zhoumh
 * @version 创建时间：2017年11月15日 下午3:19:05 
 * @Description
 */
@Service
public class Dwz {
	private static Logger logger = LoggerFactory.getLogger(Dwz.class);
	@Autowired
	private HttpConnectionManager httpConnectionManager;
	private static CloseableHttpClient httpClient = null;
	private static CloseableHttpResponse response = null; 
	private Header[] headers = null ;
	private static HttpClientContext httpContext = HttpClientContext.create();
	@PostConstruct
	public void init(){
		getHttpClient();
	}
	@PreDestroy  
    public void  dostory(){  
		closeHttpClient();
	}
	/**
	 * 百度服务
	 * @param longurl 要转换的长链接
	 * @return tinyurl 转换后的短链接
	 * @return: String
	 * @author: zhoumh
	 * @version: 创建时间：2017年11月15日 下午3:44:33 
	 * @Description: 调用百度短网址服务进行转换,百度对不知名的站点支持性很差，不建议使用
	 */
	public String baidu(String longurl){
		String tinyurl = "";
		List<NameValuePair> formparams = new ArrayList<NameValuePair>();
		formparams.add(new BasicNameValuePair("url", longurl));
		formparams.add(new BasicNameValuePair("alias", ""));
		formparams.add(new BasicNameValuePair("access_type", "web"));
		try {
			UrlEncodedFormEntity uefEntity= new UrlEncodedFormEntity(formparams, "UTF-8");
			// 发起登录请求
			response = doPost("http://dwz.cn/create.php", uefEntity);
			if (response.getStatusLine().getStatusCode()==200) {
				HttpEntity entity = response.getEntity();
				// 判断返回实体是否为空
				if (entity != null) {
					// 获取返回的内容
					String html = EntityUtils.toString(entity, "UTF-8");
					/*
					 * 判断返回值是否符合预期：
					 * {"tinyurl":"http:\/\/dwz.cn\/6R749a",
					 * "status":0,
					 * "longurl":"https://www.so.com/s?ie=utf-8&fr=none&src=360sou_newhome&
					 * q=%E7%94%B2%E5%A3%B3%E7%8B%82%E6%BD%AE%2B1054%2B%E6%B7%B1%E5%85%A5%E6%95%8C%E5%B7%A2",
					 * "err_msg":""}
					 * {"status":-1,"err_msg":"您输入的域名暂不支持生成短网址，请重新输入","longurl":""}
					 */
					tinyurl = html.substring(html.indexOf("http"),html.indexOf("\",")).replace("\\", "");
					logger.info(tinyurl);
				}
			}
		} catch (Exception e) {
			logger.error("网址转换失败！"+longurl);
			e.printStackTrace();
			// 短网址转换失败，返回长网址，确保服务调用可以继续进行
			return longurl;
		}
		return tinyurl;
	}
	/**
	 * 短网址服务
	 * @param longurl 要转换的长链接
	 * @return tinyurl 转换后的短链接
	 * @return: String
	 * @author: zhoumh
	 * @version: 创建时间：2017年11月15日 下午3:44:33 
	 * @Description: 调用短网址服务进行转换
	 */
	public String dwz(String longurl){
		String tinyurl = "";
		List<NameValuePair> formparams = new ArrayList<NameValuePair>();
		formparams.add(new BasicNameValuePair("url", longurl));
		formparams.add(new BasicNameValuePair("alias", ""));
		formparams.add(new BasicNameValuePair("https", "1"));
		try {
			UrlEncodedFormEntity uefEntity= new UrlEncodedFormEntity(formparams, "UTF-8");
			// 发起登录请求
			response = doPost("https://dwz.mn/create.aspx", uefEntity);
			if (response.getStatusLine().getStatusCode()==200) {
				HttpEntity entity = response.getEntity();
				// 判断返回实体是否为空
				if (entity != null) {
					// 获取返回的内容
					String html = EntityUtils.toString(entity, "UTF-8");
					/*
					 * 判断返回值是否符合预期：
					 * {"tinyurl":"https://dwz.mn/7SAM","status":0,"longurl":"http://www.bqg5200.com/xiaoshuo/6/6044/7226870.html","err_msg":""}
					 * {"tinyurl":"https://dwz.mn/7SAM","status":0,"longurl":"http://www.bqg5200.com/xiaoshuo/6/6044/7226870.html","err_msg":"已存在对应短网址"}
					 */
					JSONObject js = JSON.parseObject(html);
					tinyurl = js.getString("tinyurl");
					logger.info(tinyurl);
				}
			}
		} catch (Exception e) {
			logger.error("网址转换失败！"+longurl);
			e.printStackTrace();
			// 短网址转换失败，返回长网址，确保服务调用可以继续进行
			return longurl;
		}
		return tinyurl;
	}
	
	/**
	 * 速跳服务
	 * @param longurl 要转换的长链接
	 * @return tinyurl 转换后的短链接
	 * @return: String
	 * @author: zhoumh
	 * @version: 创建时间：2017年11月15日 下午3:44:33 
	 * @Description: 调用速跳服务进行转换
	 */
	public String st(String longurl){
		String tinyurl = "";
		headers = HttpHeader.custom()
				.accept("application/json, text/javascript, */*; q=0.01")
				.referer("https://st.im/")
				.userAgent("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36")
				.build();
		List<NameValuePair> formparams = new ArrayList<NameValuePair>();
		formparams.add(new BasicNameValuePair("longurl", longurl));
		// 101 速跳转换 201 新浪转换 301 百度转换
		formparams.add(new BasicNameValuePair("type", "201"));
		try {
			UrlEncodedFormEntity uefEntity= new UrlEncodedFormEntity(formparams, "UTF-8");
			// 发起登录请求
			response = doPost("https://st.im/api/shorturl/create", uefEntity);
			if (response.getStatusLine().getStatusCode()==200) {
				HttpEntity entity = response.getEntity();
				// 判断返回实体是否为空
				if (entity != null) {
					// 获取返回的内容
					String html = EntityUtils.toString(entity, "UTF-8");
					JSONObject js = JSON.parseObject(html);
					System.out.println(js);
					tinyurl = js.getJSONObject("data").getString("tinyurl");
					logger.info(tinyurl);
				}
			}
			headers = HttpHeader.custom().build();
		} catch (Exception e) {
			logger.error("网址转换失败！"+longurl);
			e.printStackTrace();
			// 短网址转换失败，返回长网址，确保服务调用可以继续进行
			return longurl;
		}
		return tinyurl;
	}
	
	/**
	 * mrw服务
	 * @param longurl 要转换的长链接
	 * @return tinyurl 转换后的短链接
	 * @return: String
	 * @author: zhoumh
	 * @version: 创建时间：2017年11月15日 下午3:44:33 
	 * @Description: 调用速跳服务进行转换
	 */
	public String mrw(String longurl){
		String tinyurl = "";
		try {
			// 发起登录请求
			response = doGet("http://mrw.so/api.php?format=json&url="+java.net.URLEncoder.encode(longurl, "UTF-8"));
			if (response.getStatusLine().getStatusCode()==200) {
				HttpEntity entity = response.getEntity();
				// 判断返回实体是否为空
				if (entity != null) {
					// 获取返回的内容
					String html = EntityUtils.toString(entity, "UTF-8");
					JSONObject js = JSON.parseObject(html);
					System.out.println(js);
					tinyurl = js.getString("url");
//					logger.info(tinyurl);
				}
			}
			headers = HttpHeader.custom().build();
		} catch (Exception e) {
			logger.error("网址转换失败！"+longurl);
			e.printStackTrace();
			// 短网址转换失败，返回长网址，确保服务调用可以继续进行
			return longurl;
		}
		return tinyurl;
	}
	/**
	 * 根据URL发起请求并返回请求结果
	 * @param url 请求链接
	 * @author zhoumh
	 * @version 创建时间：2017年10月13日 上午10:30:47
	 */
	private String getHTML(String url) {
		String html = "";
		try {
			response = doGet(url);
			HttpEntity entity = response.getEntity();
			// 判断返回实体是否为空
			if (entity != null) {
				// 获取返回的内容
				html = EntityUtils.toString(entity, "UTF-8");
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} 
		headers = HttpHeader.custom().build();
		return html;
	}
	/**
	 * 根据传入的URL和httpclient发起get请求并返回结果
	 * @param url 请求的地址
	 * @throws ClientProtocolException
	 * @throws IOException 
	 * @return: CloseableHttpResponse
	 * @author: zhoumh
	 * @version: 创建时间：2017年10月17日 上午11:04:45 
	 * @Description:
	 */
	private CloseableHttpResponse doGet(String url)
			throws ClientProtocolException, IOException {
		HttpGet httpGet = new HttpGet(url);
		// 配置请求的HEADER部分
		httpGet.addHeader(HttpHeaders.ACCEPT, "application/xml");
		// 接收返回信息
		response = getHttpClient().execute(httpGet, httpContext);
		return response;
	}
	/**
	 * 根据传入的URL和httpclient发起POST请求并返回结果
	 * @param url 请求的地址
	 * @param uefEntity 请求的表单
	 * @throws ClientProtocolException
	 * @throws IOException 
	 * @return: CloseableHttpResponse
	 * @author: zhoumh
	 * @version: 创建时间：2017年7月26日 下午5:19:23
	 * @Description: 尝试超时捕捉并切换url重试
	 */
	private CloseableHttpResponse doPost(String url, UrlEncodedFormEntity uefEntity)
			throws ClientProtocolException, IOException {
		// Post请求
		HttpPost httppost = new HttpPost(url);
		httppost.setEntity(uefEntity);
		httppost.setHeaders(headers);
		// 发送请求并接收返回信息
		response = getHttpClient().execute(httppost,httpContext);
		return response;
	}
	/**
	 * 从连接池获取httpclient
	 * @return: CloseableHttpClient
	 * @author: zhoumh
	 * @version: 创建时间：2017年10月17日 上午9:45:28 
	 * @Description:
	 */
	private CloseableHttpClient getHttpClient(){
		if (httpClient==null) {
			httpClient = httpConnectionManager.getHttpsClient();
		}
		return httpClient;
	}
	/**
	 * 关闭httpclient
	 * @return: void
	 * @author: zhoumh
	 * @version: 创建时间：2017年10月17日 上午9:45:50 
	 * @Description:
	 */
	private void closeHttpClient(){
		try {
			if (response != null) {
				response.close();
			}
			if (httpClient != null) {
				httpClient.close();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
